package com.visionblue.business.ship.base

import androidx.lifecycle.Observer
import com.visionblue.business.ship.R
import com.visionblue.business.ship.model.exception.InputException
import com.visionblue.business.ship.model.exception.ResponseException
import com.visionblue.business.ship.util.StringUtils
import com.visionblue.business.ship.util.toast

/**
 *
 * @author xlh
 * @date 2019/8/28.
 */
class DefaultObserver<T>(
    private val errorAction: ((ViewState<T>) -> Unit)? = null,
    private val loadingAction: ((ViewState<T>) -> Unit)? = null,
    private val finallyAction: ((ViewState<T>) -> Unit)? = null,
    private val action: (ViewState<T>) -> Unit
) : Observer<ViewState<T>> {
    override fun onChanged(state: ViewState<T>) {
        handleViewStateException(state, errorAction)

        if (state.isLoading) {
            loadingAction?.invoke(state)
        } else {
            finallyAction?.invoke(state)
        }

        if (state.isSuccess) {
            action(state)
        }
    }

    private fun handleViewStateException(
        state: ViewState<T>,
        errorAction: ((ViewState<T>) -> Unit)?
    ) {

        if (state.throwable != null) {
            when (state.throwable) {
                is InputException -> toast { state.throwable.message }
                is ResponseException -> {
                    doFailure(errorAction, state, state.throwable.message)
                }
                else ->
                    doFailure(errorAction, state, StringUtils.getString(R.string.net_error))
            }
        }

    }

    private fun doFailure(
        errorAction: ((ViewState<T>) -> Unit)?,
        state: ViewState<T>, errMsg: String?
    ) {
        if (errorAction != null) {
            errorAction(state)
        } else {
            toast { errMsg }
        }
    }

}

